﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aribaccio;
using BDPAutodetect.DataService;
using BDPAutodetect.Device;
using BDPAutodetect.Models;
using CommunityToolkit.Mvvm.ComponentModel;

namespace BDPAutodetect.Mgrcore
{
    /// <summary>
    /// 参数管理
    /// </summary>
    public partial class ParameterManager : BaseManager
    {
        /// <summary>
        /// 基础数据操作
        /// </summary>
        protected IDataServiceBasic DataService { get; set; }
        /// <summary>
        /// 指标管理
        /// </summary>
        protected TargetSlaveManager TargetSlaveMgr { get; set; }
        /// <summary>
        /// 参数配置数据集
        /// </summary>
        public List<MParameterData> ParameterDatas { get; set; }

        /// <summary>
        /// 是否有效存在参数信息
        /// </summary>
        public bool IsValid => this.ParameterDatas != null && this.ParameterDatas.Count > 0;

        /// <summary>
        /// 构造函数[注入]
        /// </summary>
        public ParameterManager(IDataServiceBasic argBusiness, TargetSlaveManager argTargetManager)
            : base("参数管理中心")
        {
            this.DataService = argBusiness;
            this.TargetSlaveMgr = argTargetManager;
            this.ParameterDatas = new List<MParameterData>();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public override async Task Initialize()
        {
            if (this.IsValid) return;
            if (this.ParameterDatas == null) this.ParameterDatas = new List<MParameterData>();

            //获取数据库数据
            var resultDatas = this.DataService.SelectModelItemsTask<TParameter>();
            await resultDatas.ConfigureAwait(false);
            if (resultDatas == null || !resultDatas.Result.ResultState || resultDatas.Result.Data == null || resultDatas.Result.Data.Count <= 0) return;

            //获取数据库界限数据
            var resultLimitDatas = this.DataService.SelectModelItemsTask<TParameterLimit>();
            await resultLimitDatas.ConfigureAwait(false);
            if (resultLimitDatas == null || resultLimitDatas.Result == null || !resultLimitDatas.Result.ResultState || resultLimitDatas.Result.Data.Count <= 0) return;

            List<MSlave> slaves = this.GetSlaves();
            foreach (var paramItem in resultDatas.Result.Data)
            {
                if (paramItem == null) continue;
                var slave = slaves.FirstOrDefault(v => v.ID == paramItem.SlaveID);
                var targetSlaves = this.TargetSlaveMgr.GetTargetSlaveCustomer(paramItem.SlaveID);
                if (slave == null || targetSlaves == null || targetSlaves.Count <= 0) continue;

                MParameterData parameterData = new MParameterData(paramItem.ID, paramItem.Name, slave);
                //界限数据
                var paramLimits = resultLimitDatas.Result.Data.Where(v => v.ParameterID == paramItem.ID).OrderBy(v=>v.TargetID);
                if (paramLimits != null && paramLimits.Count() > 0)
                {
                    foreach (var paramLimitItem in paramLimits)
                    {
                        if (paramLimitItem == null) continue;
                        var targetSlaveCustomer = targetSlaves.FirstOrDefault(v => v.Target.ID == paramLimitItem.TargetID);
                        parameterData.Limits.Add(new MParameterLimitData()
                        {
                            ID = paramLimitItem.ID,
                            ParameterID = paramLimitItem.ParameterID,
                            TargetSlave = targetSlaveCustomer,
                            Limit = paramLimitItem.Limit,
                            LimitTo = paramLimitItem.LimitTo,
                            LimitTime = paramLimitItem.LimitTime
                        });
                    }
                    this.ParameterDatas.Add(parameterData);
                }
                else
                {
                    var resulTask = this.DataService.DeleteWhereTask<TParameter>(v => v.ID == paramItem.ID);
                    await resulTask.ConfigureAwait(false);
                }
            }
        }

        /// <summary>
        /// 新增参数数据
        /// </summary>
        /// <returns></returns>
        public async Task<MParameterData?> InsertParam(MParameterData argParameter)
        {
            TParameter parameter = argParameter.CloneTData();
            if (this.CheckExsitsParam(parameter)) return null;

            var result = this.DataService.InsertTask(parameter);
            await result.ConfigureAwait(false);
            if (result != null && result.Result.ResultState)
            {
                var newParameter = this.DataService.SelectModelItem<TParameter>(v => v.SlaveID == parameter.SlaveID && v.Name == parameter.Name);
                if (newParameter == null || !newParameter.ResultState || newParameter.Data == null)
                {
                    var resultDelete = this.DataService.DeleteWhereTask<TParameter>(v => v.Name == argParameter.Name);
                    await resultDelete.ConfigureAwait(false);
                    return default;
                }

                bool bIsOk = true;
                MParameterData parameterData = new MParameterData(newParameter.Data.ID, newParameter.Data.Name, argParameter.Slave);
                if (argParameter.Limits != null && argParameter.Limits.Count > 0)
                {
                    foreach (var item in argParameter.Limits)
                    {
                        item.ParameterID = parameterData.ID;
                        MParameterLimitData? newParameterLimit = this.InsertParamLimit(item);
                        if (newParameterLimit == null)
                        {
                            bIsOk = false;
                            break;
                        }
                        parameterData.Limits.Add(newParameterLimit);
                    }
                }
                else
                {
                    var targets = this.TargetSlaveMgr.GetTargetSlaveCustomer(argParameter.Slave.ID);
                    if (targets == null || targets.Count <= 0)
                    {
                        var resultDeleteTask = this.DataService.DeleteWhereTask<TParameter>(v => v.ID == newParameter.Data.ID);
                        await resultDeleteTask.ConfigureAwait(false);
                        return default;
                    }
                    foreach (var item in targets.OrderBy(v=>v.Target.ID))
                    {
                        MParameterLimitData? newParameterLimit = this.InsertParamLimit(new MParameterLimitData() { ParameterID = parameterData.ID, TargetSlave = item, LimitTime = 1 });
                        if (newParameterLimit == null)
                        {
                            bIsOk = false;
                            break;
                        }
                        parameterData.Limits.Add(newParameterLimit);
                    }
                }

                if (bIsOk)
                {
                    this.ParameterDatas.Add(parameterData);
                    return parameterData;
                }
                else
                {
                    var deleteTask = this.DataService.DeleteWhereTask<TParameter>(v => v.ID == newParameter.Data.ID);
                    await deleteTask.ConfigureAwait(false);
                    deleteTask = this.DataService.DeleteWhereTask<TParameterLimit>(v => v.ParameterID == newParameter.Data.ID);
                    await deleteTask.ConfigureAwait(false);
                    return default;
                }
            }
            return default;
        }

        /// <summary>
        /// 删除参数数据
        /// </summary>
        /// <returns></returns>
        public async Task<bool> DeleteParam(MParameterData argParameter)
        {
            if (argParameter == null) return false;
            Task<Result> result = this.DataService.DeleteWhereTask<TParameter>(v => v.ID == argParameter.ID);
            await result.ConfigureAwait(false);
            if (result != null && result.Result.ResultState)
            {
                //删除参数界限
                Task<Result> resultLimit = this.DataService.DeleteWhereTask<TParameterLimit>(v => v.ParameterID == argParameter.ID);
                await resultLimit.ConfigureAwait(false);
                //移除缓存
                var currParameter = this.ParameterDatas.First(v => v.ID == argParameter.ID);
                this.ParameterDatas.Remove(currParameter);
                return true;
            }
            else { return false; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="argParameter"></param>
        /// <returns></returns>
        public async Task<bool> UpdateParam(MParameterData argParameter)
        {
            if (argParameter == null) return false;
            TParameter parameter = argParameter.CloneTData();
            if (this.CheckExsitsParam(parameter)) return false;

            Task<Result> result = this.DataService.UpdateWhereTask<TParameter>(parameter, v => v.ID == argParameter.ID);
            await result.ConfigureAwait(false);
            if (result != null && result.Result.ResultState)
            {
                var parameterData = this.ParameterDatas.First(v => v.ID == argParameter.ID);
                parameterData.Name = argParameter.Name;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="argParameterLimit"></param>
        /// <returns></returns>
        public MParameterLimitData? InsertParamLimit(MParameterLimitData argParameterLimit)
        {
            if (argParameterLimit == null || argParameterLimit.TargetSlave == null) return null;
            var result = this.DataService.Insert<TParameterLimit>(argParameterLimit.CloneTData());
            if (result == null || !result.ResultState) return null;

            var newParameter = this.DataService.SelectModelItem<TParameterLimit>(v => v.ParameterID == argParameterLimit.ParameterID && v.TargetID == argParameterLimit.TargetSlave.Target.ID);
            if (newParameter == null || !newParameter.ResultState || newParameter.Data == null)
            {
                return default;
            }
            argParameterLimit.ID = newParameter.Data.ID;
            return argParameterLimit;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="argParameterLimit"></param>
        public async Task<bool> UpdateParamLimit(MParameterLimitData argParameterLimit)
        {
            Task<Result> result = this.DataService.UpdateWhereTask<TParameterLimit>(argParameterLimit.CloneTData(), v => v.ID == argParameterLimit.ID);
            await result.ConfigureAwait(false);
            if (result == null || result.Result == null || !result.Result.ResultState) return false;

            var parameter = this.ParameterDatas.First(v => v.ID == argParameterLimit.ParameterID);
            if (parameter != null)
            {
                MParameterLimitData parameterLimit = parameter.Limits.First(v => v.ID == argParameterLimit.ID);
                if (parameterLimit != null)
                {
                    parameterLimit.Limit = argParameterLimit.Limit;
                    parameterLimit.LimitTo = argParameterLimit.LimitTo;
                    parameterLimit.LimitTime = argParameterLimit.LimitTime;
                }
            }
            return true;
        }

        /// <summary>
        /// 获取参数指标界限
        /// </summary>
        /// <param name="argSlave"></param>
        /// <returns></returns>
        public List<MParameterData> GetParameters(MSlave argSlave)
        {
            if (!this.IsValid) return new List<MParameterData>();
            var parameters = this.ParameterDatas.Where(v => v.Slave.ID == argSlave.ID);
            return parameters != null ? parameters.ToList() : new List<MParameterData>();
        }

        /// <summary>
        /// 获取从机设备列表
        /// </summary>
        /// <returns></returns>
        public List<MSlave> GetSlaves()
        {
            return this.TargetSlaveMgr.GetSlaves();
        }

        /// <summary>
        /// 检查参数名称是否存在
        /// </summary>
        /// <param name="argParameterName"></param>
        /// <returns></returns>
        protected bool CheckExsitsParam(TParameter argParameter)
        {
            Result check = this.DataService.Exsits<TParameter>(v => v.SlaveID == argParameter.SlaveID && v.Name.Equals(argParameter.Name, StringComparison.OrdinalIgnoreCase));
            return (check != null && check.ResultState);
        }
    }
}
